package com.ruoyi.yl.service.impl;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.domain.Activity;
import com.ruoyi.common.domain.CommentInfo;
import com.ruoyi.common.domain.Orders;
import com.ruoyi.common.domain.PointRecords;
import com.ruoyi.common.domain.constant.RedisKey;
import com.ruoyi.common.domain.constant.RoleConstant;
import com.ruoyi.common.domain.constant.enums.MessTopicAndTag;
import com.ruoyi.common.domain.constant.to.MessageActivityTo;
import com.ruoyi.common.mapper.CommentInfoMapper;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.system.api.constant.YlStatus;
import com.ruoyi.yl.domain.Users;
import com.ruoyi.yl.rocketmq.product.MessageProducer;
import com.ruoyi.yl.service.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class CommentInfoServiceImpl extends ServiceImpl<CommentInfoMapper, CommentInfo> implements ICommentInfoService {

    @Resource
    private RedisService redisService;
    @Resource
    private MessageProducer messageProducer;

    @Resource
    private IOrdersService  ordersService;

    @Resource
    private IActivityService activityService;


    @Resource
    private IUsersService usersService;


    @Resource
    private IPointRecordsService  pointRecordsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrderComment(CommentInfo info) {

        /*
          1， 赛选复合要求的用户 角色信息
          2.  保存评论信息
          3.  Mq通知触发
         */

        //1. 获取客服信息
        Long nextOnlineAuditor = getNextOnlineAuditor();
        info.setSysUserId(nextOnlineAuditor);
        info.setCreatedAt(LocalDateTime.now());
        info.setUpdatedAt(LocalDateTime.now());
        info.setReviewStatus(Orders.CURRENT_TYPE.WAITING_REVIEW.getValue() );
        info.setReviewStatusDesc(Orders.CURRENT_TYPE.WAITING_REVIEW.getDesc());
        info.setStatus(YlStatus.NORMAL.getCode());
        this.getBaseMapper().insert(info);


        //2.修改订单状态
        ordersService.updateOrderCurrentStatusByOrderNo(info.getOrderNo(),Orders.CURRENT_TYPE.WAITING_REVIEW);



        //3. 通知mq
        messageProducer.sendMessageWithTagObj(MessTopicAndTag.YL_COMMENT_NOTICE_AUDITORS,
                MessageActivityTo.builder()
                        .sysUserId(nextOnlineAuditor)
                        .build()
        );
    }


    @Override
    public void reviewTrue(String orderNo) {
        //1. 操作订单相关
        Orders orders = ordersService.selectByOrderNo(orderNo);
        orders.setCurrentStatus(Orders.CURRENT_TYPE.REVIEW_APPROVED.getValue());
        orders.setUpdatedAt(LocalDateTime.now());
        ordersService.saveOrUpdate(orders);

        //2. 操作活动相关
        Activity activity = activityService.selectActivityById(orders.getActivityId());
        BigDecimal discountAmount = activity.getDiscountAmount();

        //3. 操作积分信息
        Users users = usersService.selectById(orders.getUserId());
        users.setPoints(users.getPoints()+discountAmount.intValue());
        usersService.saveOrUpdate(users);

        //4. 记录积分操作信息
        pointRecordsService.savePoint(PointRecords.builder()
                .userId(users.getId())
                .pointType(PointRecords.POINT_TYPE.COMMENT_REWARD.getValue())
                .points(+orders.getDemandAmount().intValue())
                .balance(users.getPoints())
                .relatedId(orders.getId())
                .description(PointRecords.POINT_TYPE.COMMENT_REWARD.getDesc())
                .createdAt(LocalDateTime.now())
                .build());

    }

    @Override
    public void reviewFalse(String orderNo, String reviewStatusDesc) {
        //1. 操作订单相关
        Orders orders = ordersService.selectByOrderNo(orderNo);
        orders.setCurrentStatus(Orders.CURRENT_TYPE.REVIEW_REJECT.getValue());
        orders.setUpdatedAt(LocalDateTime.now());
        orders.setRejectReason(reviewStatusDesc);
        ordersService.saveOrUpdate(orders);
    }

    private final AtomicInteger index = new AtomicInteger(0);

    @Resource
    private RedisTemplate<String, Long> redisTemplate;
    /**
     * 获取下一个在线审核员
     */
    public Long getNextOnlineAuditor() {
        //yi. 如果有在线审核专员优先发在线审核专员
        Object value = redisService.getZSetValue(String.format(RedisKey.ONLINE_AUDITORS, RoleConstant.AUDITORS));
        if (ObjectUtils.isNotEmpty(value)) {
            return Long.parseLong(String.valueOf(value));
        }


        //er. 如果没有那就返回数据库查的吧

        // 1. 从 Redis 取在线列表
        List<Long> onlineAuditors = redisTemplate.opsForList().range(RedisKey.AUDITORS_KEY_ALL, 0, -1);

        if (onlineAuditors == null || onlineAuditors.isEmpty()) {
            // 2. 如果 Redis 为空，从数据库加载
            onlineAuditors = this.getBaseMapper().selectSysUserIdsByRole(RoleConstant.AUDITORS);

            if (onlineAuditors == null || onlineAuditors.isEmpty()) {
                return null; // 数据库也没有 -> 无可用审核员
            }

            // 3. 加载进 Redis（例如保存 10 分钟）
            redisTemplate.delete(RedisKey.AUDITORS_KEY_ALL); // 清理旧数据
            redisTemplate.opsForList().rightPushAll(RedisKey.AUDITORS_KEY_ALL, onlineAuditors);
            redisTemplate.expire(RedisKey.AUDITORS_KEY_ALL, java.time.Duration.ofMinutes(10));
        }

        // 4. 轮询取一个
        int i = Math.abs(index.getAndIncrement() % onlineAuditors.size());
        return onlineAuditors.get(i);
    }

}
